package com.shopping_back.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shopping_back.mapper.CategoryMapper;
import com.shopping_back.mapper.SkuMapper;
import com.shopping_back.pojo.dto.PageDTO;
import com.shopping_back.pojo.dto.ProductDTO;
import com.shopping_back.pojo.dto.SkuDTO;
import com.shopping_back.pojo.dto.SpuSearchDTO;
import com.shopping_back.pojo.entity.Category;
import com.shopping_back.pojo.entity.Sku;
import com.shopping_back.pojo.entity.Spu;
import com.shopping_back.mapper.SpuMapper;
import com.shopping_back.pojo.vo.ProductVO;
import com.shopping_back.pojo.vo.SkuVO;
import com.shopping_back.service.ICategoryService;
import com.shopping_back.service.ISkuService;
import com.shopping_back.service.ISpuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品SPU表 服务实现类
 * </p>
 *
 * @author Jack
 * @since 2025-07-12
 */
@Service
@RequiredArgsConstructor
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements ISpuService {

    private final SkuMapper skuMapper;

    private final SpuMapper spuMapper;

    private final ICategoryService categoryService;

    private final CategoryMapper categoryMapper;

    private final ISkuService skuService;

    @Override
    public PageDTO<ProductDTO> getProductsByCategory(Long categoryId, Integer page, Integer size) {
        QueryWrapper<Spu> query = new QueryWrapper<>();
        query.eq("category_id", categoryId).eq("status", 1);
        Page<Spu> pageRequest = new Page<>(page, size);
        Page<Spu> result = spuMapper.selectPage(pageRequest, query);

        PageDTO<ProductDTO> pageDTO = new PageDTO<>();
        pageDTO.setList(result.getRecords().stream().map(this::convertToProductDTO).collect(Collectors.toList()));
        pageDTO.setTotal(result.getTotal());
        pageDTO.setCurrentPage(page);
        pageDTO.setPageSize(size);
        return pageDTO;
    }

    private ProductDTO convertToProductDTO(Spu spu) {
        ProductDTO dto = new ProductDTO();
        dto.setId(spu.getId());
        dto.setTitle(spu.getTitle());
        dto.setMainImage(spu.getMainImage());

        QueryWrapper<Sku> skuQuery = new QueryWrapper<>();
        skuQuery.eq("spu_id", spu.getId());
        List<Sku> skus = skuMapper.selectList(skuQuery);
        List<SkuDTO> skuDTOs = skus.stream().map(sku -> {
            SkuDTO skuDTO = new SkuDTO();
            skuDTO.setId(sku.getId());
            skuDTO.setSpecsJson(sku.getSpecsJson());
            skuDTO.setPrice(sku.getPrice());
            skuDTO.setStock(sku.getStock());
            skuDTO.setSkuImage(sku.getSkuImage());
            return skuDTO;
        }).collect(Collectors.toList());
        dto.setSkus(skuDTOs);

        dto.setPrice(skuDTOs.stream()
                .map(SkuDTO::getPrice)
                .min(BigDecimal::compareTo)
                .orElse(BigDecimal.ZERO));
        return dto;
    }

    @Override
    public Map<String,Object> search(SpuSearchDTO dto){

        LambdaQueryWrapper<Spu> qw = new LambdaQueryWrapper<>();

        /* 关键字模糊，必加 */
        qw.eq(Spu::getStatus, 1)                       // 只查上架
                .like(Spu::getTitle, dto.getKeyword().trim());

        System.out.println("本次搜索命中的 categoryId 列表：" + dto.getCategoryId());
        /* AND 关系的可选条件 */
        if (dto.getCategoryId() != null) {
            qw.eq(Spu::getCategoryId, dto.getCategoryId());

        }

        if (dto.getMinPrice() != null) {
            qw.apply("id IN (SELECT spu_id FROM sku WHERE price >= {0})",
                    dto.getMinPrice());
        }
        if (dto.getMaxPrice() != null) {
            qw.apply("id IN (SELECT spu_id FROM sku WHERE price <= {0})",
                    dto.getMaxPrice());
        }

        if (dto.getMinStock() != null && dto.getMinStock() >= 0) {
            qw.apply("id IN (SELECT spu_id FROM sku WHERE stock >= {0})", dto.getMinStock());
        }

        // 排序逻辑
        boolean asc = "asc".equalsIgnoreCase(dto.getSortOrder());

        switch (dto.getSortBy().toLowerCase()) {
            case "price" -> {
                String order = asc ? "ASC" : "DESC";
                qw.last(String.format(
                        "ORDER BY (SELECT MIN(price) FROM sku s WHERE s.spu_id = spu.id) %s", order));
            }
            case "sales" -> {
                String order = asc ? "ASC" : "DESC";
                qw.last(String.format(
                        "ORDER BY (SELECT SUM(sales) FROM sku s WHERE s.spu_id = id) %s", order));
            }
            case "time", "default" -> {
                // 上新时间（create_time）
                if (asc) {
                    qw.orderByAsc(Spu::getCreateTime);
                } else {
                    qw.orderByDesc(Spu::getCreateTime);
                }
            }
        }

        // 用 dto 自带的 pageNum / pageSize 进行真正分页查询
        Page<Spu> mpPage = this.page(
                new Page<>(dto.getPageNum(), dto.getPageSize()),
                qw);

        // 把 Spu 转成前端需要的 ProductDTO
        List<ProductDTO> records = mpPage.getRecords()
                .stream()
                .map(this::convertToProductDTO)
                .toList();

        /* 封装 PageDTO 返回 */
        PageDTO<ProductDTO> pageDTO = new PageDTO<>();
        pageDTO.setList(records);
        pageDTO.setTotal(mpPage.getTotal());
        pageDTO.setCurrentPage(dto.getPageNum());
        pageDTO.setPageSize(dto.getPageSize());

        //不分页地统计所有命中类目 id
        List<Long> catIds = this.listObjs(qw.select(Spu::getCategoryId), o -> (Long) o)
                .stream().distinct().toList();

        //查类目名称
        List<Category> categoryList = catIds.isEmpty()
                ? List.of()
                : categoryService.listByIds(catIds);

        Map<String,Object> resp = new HashMap<>();
        resp.put("page", pageDTO);
        resp.put("categoryList", categoryList);
        return resp;
    }

    @Override
    public Spu getSpuWithSkuList(Long spuId) {
        // 查询SPU基本信息
        Spu spu = getById(spuId);
        if (spu == null || spu.getStatus() == 0) {
            return null;
        }

        // 查询关联的SKU列表
        List<Sku> skuList = skuService.list(new LambdaQueryWrapper<Sku>()
                .eq(Sku::getSpuId, spuId));

        // 将SKU列表设置到SPU对象中
        spu.setSkuList(skuList);

        return spu;
    }

    @Override
    public Page<ProductVO> getProducts(Long merchantId, Integer page, Integer size) {
        Page<Spu> spuPage = new Page<>(page, size);
        LambdaQueryWrapper<Spu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Spu::getMerchantId, merchantId)
                .orderByDesc(Spu::getId);

        Page<Spu> result = spuMapper.selectPage(spuPage, queryWrapper);

        Page<ProductVO> voPage = new Page<>();
        voPage.setTotal(result.getTotal());
        voPage.setRecords(result.getRecords().stream().map(spu -> {
            ProductVO vo = new ProductVO();
            vo.setId(spu.getId());
            vo.setTitle(spu.getTitle());
            vo.setCategoryId(spu.getCategoryId());
            vo.setMerchantId(spu.getMerchantId());
            vo.setMainImage(spu.getMainImage());
            vo.setDetailHtml(spu.getDetailHtml());
            vo.setStatus(spu.getStatus());

            Category category = categoryMapper.selectById(spu.getCategoryId());
            vo.setCategoryName(category != null ? category.getName() : "");

            List<Sku> skus = skuMapper.selectBySpuId(spu.getId());
            vo.setSkus(skus.stream().map(sku -> {
                SkuVO skuVO = new SkuVO();
                skuVO.setId(sku.getId());
                skuVO.setSpuId(sku.getSpuId());
                skuVO.setSpecsJson(sku.getSpecsJson());
                skuVO.setPrice(sku.getPrice());
                skuVO.setStock(sku.getStock());
                skuVO.setWarningStock(sku.getWarningStock());
                skuVO.setSkuImage(sku.getSkuImage());
                return skuVO;
            }).collect(Collectors.toList()));

            return vo;
        }).collect(Collectors.toList()));

        return voPage;
    }

    @Transactional
    public void createProduct(ProductDTO productDTO) {
        Spu spu = new Spu();
        spu.setTitle(productDTO.getTitle());
        spu.setCategoryId(productDTO.getCategoryId());
        spu.setMerchantId(productDTO.getMerchantId());
        spu.setMainImage(productDTO.getMainImage());
        spu.setDetailHtml(productDTO.getDetailHtml());
        spu.setStatus(3); // 默认待审核
        spuMapper.insert(spu);

        for (SkuDTO skuDTO : productDTO.getSkus()) {
            System.out.println(skuDTO);
            Sku sku = new Sku();
            sku.setSpuId(spu.getId());
            sku.setSpecsJson(skuDTO.getSpecsJson());
            sku.setPrice(skuDTO.getPrice());
            sku.setStock(skuDTO.getStock());
            sku.setWarningStock(skuDTO.getWarningStock());
            sku.setSkuImage(skuDTO.getSkuImage());
            skuMapper.insert(sku);
        }
    }

    @Transactional
    public void updateProduct(ProductDTO productDTO) {
        Spu spu = spuMapper.selectById(productDTO.getId());
        if (spu == null) {
            throw new RuntimeException("商品不存在");
        }
        spu.setTitle(productDTO.getTitle());
        spu.setCategoryId(productDTO.getCategoryId());
        spu.setMainImage(productDTO.getMainImage());
        spu.setDetailHtml(productDTO.getDetailHtml());
        spu.setStatus(3); // 待审核
        spuMapper.updateById(spu);

        LambdaQueryWrapper<Sku> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Sku::getSpuId, spu.getId());
        skuMapper.delete(queryWrapper);

        for (SkuDTO skuDTO : productDTO.getSkus()) {
            Sku sku = new Sku();
            sku.setSpuId(spu.getId());
            sku.setSpecsJson(skuDTO.getSpecsJson());
            sku.setPrice(skuDTO.getPrice());
            sku.setStock(skuDTO.getStock());
            sku.setWarningStock(skuDTO.getWarningStock());
            sku.setSkuImage(skuDTO.getSkuImage());
            skuMapper.insert(sku);
        }
    }

    @Transactional
    public void toggleProductStatus(Long spuId, Integer status) {
        Spu spu = spuMapper.selectById(spuId);
        if (spu == null) {
            throw new RuntimeException("商品不存在");
        }
        spu.setStatus(status);
        spuMapper.updateById(spu);
    }

    @Override
    public PageDTO<Spu> listPending(Integer page, Integer size) {
        Page<Spu> spuPage = new Page<>(page, size);

        LambdaQueryWrapper<Spu> qw = new LambdaQueryWrapper<Spu>()
                // 如有状态过滤需求在这里加 .eq(...)
                .orderByDesc(Spu::getCreateTime);

        Page<Spu> result = spuMapper.selectPage(spuPage, qw);

        PageDTO<Spu> dto = new PageDTO<>();
        dto.setTotal(result.getTotal());
        dto.setCurrentPage(page);
        dto.setPageSize(size);
        dto.setList(result.getRecords());   // ← 直接塞 SPU 列表
        return dto;
    }


    private ProductVO toVO(Spu spu) {
        ProductVO vo = new ProductVO();
        vo.setId(spu.getId());
        vo.setTitle(spu.getTitle());
        vo.setCategoryId(spu.getCategoryId());
        vo.setMerchantId(spu.getMerchantId());
        vo.setMainImage(spu.getMainImage());
        vo.setDetailHtml(spu.getDetailHtml());
        vo.setStatus(spu.getStatus());

        Category category = categoryMapper.selectById(spu.getCategoryId());
        vo.setCategoryName(category != null ? category.getName() : "");

        List<Sku> skus = skuMapper.selectBySpuId(spu.getId());
        vo.setSkus(skus.stream().map(sku -> {
            SkuVO skuVO = new SkuVO();
            skuVO.setId(sku.getId());
            skuVO.setSpuId(sku.getSpuId());
            skuVO.setSpecsJson(sku.getSpecsJson());
            skuVO.setPrice(sku.getPrice());
            skuVO.setStock(sku.getStock());
            skuVO.setWarningStock(sku.getWarningStock());
            skuVO.setSkuImage(sku.getSkuImage());
            return skuVO;
        }).toList());

        return vo;
    }

}
